package net.thermetics.fx.controllers;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import net.thermetics.fx.auth.GaeUser;
import net.thermetics.fx.forms.ReportForm;
import net.thermetics.fx.model.Report;
import net.thermetics.fx.model.ReportVote;
import net.thermetics.fx.services.ReportService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

@Controller
@RequestMapping("/report")
@SessionAttributes({ "report" })
public class ReportController extends AbstractController {
	@Autowired
	private ReportService reportService;
		
	/**
	 * Initialize the hint text for the view. Makes
	 * sure it's always part of the model.
	 * @return The hint text for the vote comment box.
	 */
	@ModelAttribute("hintText")
	public String getHintText() {
		return "Vote comments (will be posted)";
	}
	
	@ModelAttribute("violationList")
	public List<String> violationList() {
		List<String> violations = new ArrayList<String>();
		violations.add("No Violation");
		violations.add("Flaming");
		violations.add("Trolling");
		violations.add("Spamming");
		violations.add("Campaigning");
		violations.add("Congregation Forums");
		violations.add("Controversial Topics");
		violations.add("Disruptive Behavior");
		violations.add("Vulgarity");
		violations.add("Copyright");
		violations.add("Bypassing Ban");
		violations.add("Brinking");
		violations.add("Off-Topic");
		violations.add("Discussing Staff Actions");
		violations.add("Preamble");
		violations.add("Harassment");
		violations.add("Soteriology FSGs");
		violations.add("CWR FSGs");
		violations.add("Forum SoP");
		/*
		Men's Health/Women's Health?
		 */
		return violations;
	}
	
	@ModelAttribute("moreViolations")
	public List<String> moreViolations() {
		List<String> violations = new ArrayList<String>();
		violations.add("Blasphemy");
		violations.add("Promotion/Proselytizing");
		violations.add("Forum Restriction");
		violations.add("Google Ads");
		violations.add("Spiritual Warfare");
		violations.add("e-Exorcism/Online Deliverance");
		violations.add("Prophecy Thread");
		violations.add("Giving 'Professional' Advice");
		violations.add("Advising Against Medicine");
		violations.add("Chat Box Violation");
		violations.add("Satanism");
		violations.add("Impersonation");
		violations.add("Confidentiality");
		violations.add("Legalities");
		violations.add("Provide Supporting Statements");
		violations.add("Suicide Risk");
		
		return violations;
	}
	
	@ModelAttribute("actionList")
	public List<String> actionList() {
		List<String> actions = new ArrayList<String>();
		actions.add("Delete");
		actions.add("Edit");
		actions.add("Ban");
		actions.add("Move");
		actions.add("Thread Cleanup");
		actions.add("Close Thread");
		actions.add("PM Only");
		
		return actions;
	}
	
	@ModelAttribute("submission")
	public ReportForm createForm(@PathVariable String id) {
		Report report = loadReport(id);
		GaeUser user = getCurrentAuth().getPrincipal();
		ReportVote currVote = loadUserVote(report, user);
		
		
		ReportForm fbo = new ReportForm();
		fbo.setReport(report);
		
		//Set action
		if (currVote.getAction() != null) {
			fbo.setAction(currVote.getAction());
		}
		else {
			fbo.setAction("None");	
		}
		
		fbo.setViolations(currVote.getViolationList());
		fbo.setComment(currVote.getComment());

		
		return fbo;
	}
	
	private Report loadReport(String id) {
		System.out.println("Loading report object");
		Report report = reportService.getReport(id);
		
		if (report == null) {
			System.out.println("Creating new report.");
			report = reportService.createReport(id);
		}
		else {
			System.out.println("Report loaded");
		}
		
		return report;
	}
	
	private ReportVote loadUserVote(Report report, GaeUser user) {
		ReportVote userVote = report.getVoteForUser(user);
		if (userVote == null) {
			userVote = reportService.createVote(report, user);
		}
		
		return userVote;
	}

	@RequestMapping(value = "{id}", method = RequestMethod.GET)
	public String loadForm(@PathVariable String id, @ModelAttribute("submission") ReportForm form, Model model) {	
		//Finish setting up model here.
		Map<String, Integer> voteCombos = reportService.getVoteCombinations(form.getReport());
		model.addAttribute("voteCombos", voteCombos);
		
		if (form.getViolations().size() == 0) {
			model.addAttribute("hasVoted", false);
		}
		else {
			model.addAttribute("hasVoted", true);
		}
		
		//Need to pass this because Spring is too dumb to maintain
		//it as part of the ReportForm for some reason.
		model.addAttribute("report", form.getReport());
		
		return "report/threadUpdate";
	}
	
	@RequestMapping(value = "{id}", method = RequestMethod.POST)
	public String processSubmit(@ModelAttribute Report report, @ModelAttribute ReportForm submission, SessionStatus session, ModelMap model) {
		//Block the default hint text from getting in to the datastore.
		if (submission.getComment().equals(getHintText())) {
			submission.setComment("");
		}
		
		GaeUser user = super.getCurrentAuth().getPrincipal();
		
		ReportVote currentVote = report.getVoteForUser(user);
		currentVote.setAction(submission.getAction());
		currentVote.setComment(submission.getComment());
		
		//Set up violation, if there is one.
		//If not, clear the action field and put a special "no violation selected"
		String violation = "";
		if (submission.getViolations() != null) {
			Collections.sort(submission.getViolations());
			for (String vio : submission.getViolations()) {
				violation += vio + ", ";
			}
			
			violation = violation.substring(0, violation.length() - 2); //remove ", "
		}
		else {
			violation = "No violation selected";
			currentVote.setAction("");
		}

		currentVote.setViolation(violation);
		report.removeVote(currentVote);
		report.addVote(currentVote);
		
		reportService.updateReport(report);

		session.setComplete();
		model.clear(); //Make sure model doesn't show up in URL...
		return "redirect:/app/report/" + report.getThreadID();
	}
}
